import wepy from 'wepy'
import { values } from 'lodash'
import Auth from './auth'
import Tips from './tips'
import { storageKey } from '../config'

/**
 * 封装微信请求接口
 *
 * @param options 请求参数
 * @param loading 是否显示loading
 * @param type 请求方式 request|uploadFile|downloadFile
 * @returns {Promise.<*>}
 */
const request = async (options, loading = true, type = 'request') => {
  // 设置 Token 请求头
  let token = wepy.getStorageSync(storageKey.accessToken)
  if (options.header) {
    options.header['Authorization'] = `Bearer ${token}`
    options.header['X-Requested-With'] = 'XMLHttpRequest'
  } else {
    options.header = {
      'Authorization': `Bearer ${token}`,
      'X-Requested-With': 'XMLHttpRequest'
    }
  }
  const method = wepy[type](options)
  // 显示 loading
  if (loading) {
    let tips = '加载中'
    if (type === 'uploadFile') {
      tips = '上传中'
      method.progress && method.progress((res) => {
        Tips.loading(`${tips} ${res.progress} %`, true, true)
      })
    }
    if (type === 'downloadFile') {
      tips = '下载中'
      method.progress && method.progress((res) => {
        Tips.loading(`${tips} ${res.progress} %`, true, true)
      })
    }
    Tips.loading(tips)
  }
  // 请求接口
  let response = await method.catch(() => {
    wepy.showModal({
      title: '提示',
      content: '网络错误，请联系管理员',
      showCancel: false,
      confirmColor: '#ffd200'
    })
  })
  // 关闭 loading
  if (loading) {
    Tips.loaded()
  }

  const statusCode = parseInt(response.statusCode)
  const data = response.data || response.tempFilePath || response
  // 处理返回情况
  if (statusCode < 300) {
    // 请求成功 直接返回数据
    return data
  } else if (statusCode === 401) {
    // 没有登陆 登陆后再次请求
    await Auth.login()
    const resp = await request(options)
    return resp
  } else {
    // 状态码大于 300 的其他情况 直接弹窗
    const content = data.errors ? values(data.errors).join('\n') : data.message
    wepy.showModal({
      title: '提示',
      content: content,
      showCancel: false,
      confirmColor: '#ffd200'
    })
    return Promise.reject(new Error(content))
  }
}

/**
 * GET 方法
 *
 * @param url 请求地址
 * @param data 请求数据
 * @param header 请求头
 * @param loading 是否显示loading
 * @returns {Promise.<*>}
 */
const get = async (url, data, header, loading = true) => {
  const options = {
    url,
    method: 'GET',
    data,
    header
  }
  return request(options, loading)
}

/**
 * POST 方法
 *
 * @param url 请求地址
 * @param data 请求数据
 * @param header 请求头
 * @param loading 是否显示loading
 * @returns {Promise.<*>}
 */
const post = async (url, data, header, loading = true) => {
  const options = {
    url,
    method: 'POST',
    data,
    header
  }
  return request(options, loading)
}

/**
 * PUT 方法
 *
 * @param url 请求地址
 * @param data 请求数据
 * @param header 请求头
 * @param loading 是否显示loading
 * @returns {Promise.<*>}
 */
const put = async (url, data, header, loading = true) => {
  const options = {
    url,
    method: 'PUT',
    data,
    header
  }
  return request(options, loading)
}

/**
 * DELETE 方法
 *
 * @param url 请求地址
 * @param data 请求数据
 * @param header 请求头
 * @param loading 是否显示loading
 * @returns {Promise.<*>}
 */
const del = async (url, data, header, loading = true) => {
  const options = {
    url,
    method: 'DELETE',
    data,
    header
  }
  return request(options, loading)
}

const uploadFile = async (url, images, loading = true, ops = {}) => {
  const options = {
    url: url,
    filePath: images,
    name: ops.name || 'file',
    header: ops.header || {},
    formData: ops.formData || {}
  }
  return request(options, loading, 'uploadFile')
}

const downloadFile = async (url, images, loading = true, ops = {}) => {
  const options = {
    url: url,
    header: ops.header || {}
  }
  return request(options, loading, 'downloadFile')
}

export default {
  request,
  get,
  post,
  put,
  del,
  uploadFile,
  downloadFile
}
